package top.jiangqiang.qianyi.common.base.service;

import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.github.yulichang.base.MPJBaseService;
import com.github.yulichang.query.MPJQueryWrapper;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.toolkit.MPJWrappers;
import com.github.yulichang.wrapper.DeleteJoinWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.github.yulichang.wrapper.UpdateJoinWrapper;
import org.dromara.hutool.core.text.StrUtil;
import top.jiangqiang.qianyi.common.base.model.entity.BaseEntity;
import top.jiangqiang.qianyi.common.base.model.request.BasePageRequestWithSort;
import top.jiangqiang.qianyi.common.exception.Error400Exception;

import java.io.Serializable;
import java.util.List;

import static top.jiangqiang.qianyi.common.constants.http.Error400Status.BAD_REQUEST_SORT_FIELD_DOES_NOT_EXIST;

/**
 * 此类用于操作数据库
 *
 * @author jiangqiang
 * @date 2022-07-16
 */
public interface BaseDbService<T extends BaseEntity> extends MPJBaseService<T> {

    /**
     * 获取表信息
     *
     * @return
     */
    default TableInfo getTableInfo() {
        return TableInfoHelper.getTableInfo(getEntityClass());
    }

    /**
     * 获取当前实体类对应的表名
     *
     * @return
     */
    default String getTableName() {
        TableInfo tableInfo = getTableInfo();
        return tableInfo.getTableName();
    }

    /**
     * 根据id查询数据，并转换为指定类型
     *
     * @param id     主键
     * @param tClass 目标类型
     */
    default <V> V getById(Serializable id, Class<V> tClass) {
        //这里不能通过T::getId获取主键字段名
        String keyColumn = getTableInfo().getKeyColumn();
        return lambdaJoinWrapper().eq(keyColumn, id).one(tClass);
    }

    default MPJLambdaWrapper<T> lambdaJoinWrapper() {
        //参数是主表的类型
        return MPJWrappers.lambdaJoin(getEntityClass());
    }

    default MPJQueryWrapper<T> queryJoinWrapper() {
        return MPJWrappers.queryJoin(getEntityClass());
    }

    default DeleteJoinWrapper<T> deleteJoinWrapper() {
        return JoinWrappers.delete(getEntityClass());
    }

    default UpdateJoinWrapper<T> updateJoinWrapper() {
        return JoinWrappers.update(getEntityClass());
    }

    /**
     * 根据指定字段排序
     *
     * @param request BasePageRequestWithSort
     * @return MPJLambdaWrapper
     */
    default <U extends BasePageRequestWithSort> MPJLambdaWrapper<T> lambdaJoinWrapperWithSort(U request) {
        String sortField = request.getSortField();
        if (StrUtil.isNotBlank(sortField)) {
            TableInfo tableInfo = getTableInfo();
            String keyProperty = tableInfo.getKeyProperty();
            String column = sortField.equals(keyProperty) ? tableInfo.getKeyColumn() : null;
            if (column == null) {
                List<TableFieldInfo> fieldList = tableInfo.getFieldList();
                for (TableFieldInfo tableFieldInfo : fieldList) {
                    if (tableFieldInfo.getProperty().equals(sortField)) {
                        column = tableFieldInfo.getColumn();
                        break;
                    }
                }
            }
            if (column != null) {
                return lambdaJoinWrapper()
                        .orderBy(true, request.getAsc(), column);
            } else {
                throw new Error400Exception(BAD_REQUEST_SORT_FIELD_DOES_NOT_EXIST);
            }
        } else {
            return lambdaJoinWrapper();
        }
    }
}
